<?php
/**
 * FastApp.
 * 8/12/24
 * @Author 深色的海 (wx:deepsea_0024)
 * @Contact telegram:deepsea159
 */

namespace App\Fastapp\Api\Service\Pay\Platform;

use App\Fastapp\Api\Service\Account\WalletService;
use App\Fastapp\Listener\Event\AccountOrderPayEvent;
use App\Fastapp\Model\AccountRecharge;
use App\Fastapp\Model\AccountWithdrawal;
use App\Fastapp\Model\FastappPay;
use App\Mall\Model\MallOrder;

class ShPayService
{
    public static array $config = [];

    public static function pay(array $data): array
    {
        $res = self::post('/v1/trans/payIn', [
            'transAmt' => '' . $data['amount'],
            'outTradeNo' => $data['order_id'],
            'subject' => $data['subject'],
            'mobile' => $data['mobile'],
        ]);
        if (empty($res['result'])) return $data;
        return [
            'url' => $res['result']['link'],
            'trans_no' => $res['result']['transNo'],
            'out_trade_no' => $data['order_id'],
            'amount' => $data['amount'],
            'to_no' => self::getConfig()['merchant_id']
        ];
    }

    public static function payOut(AccountWithdrawal $md): bool
    {
        try {
            $data = self::post('/v1/trans/payOut', [
                'transAmt' => $md->amount,
                'outTradeNo' => 'W' . $md->id,
                'subject' => 'withdrawal',
                'pixType' => $md->account_type, //CPF
                'accountNo' => $md->account,
                'accountName' => 'withdrawal' . $md->user_id,
            ]);
            if ($data['success']) {
                return true;
            }
        } catch (\Throwable $throwable) {
            sys_notify('代付失败: 提现id ' . $md->id . ' ' . $throwable->getMessage());
        }
        return false;
    }

    public static function payed(array $data): string
    {
        $sign = $data['sign'];
        if ($sign == self::sign([
                'transNo' => $data['transNo'],
                'completionTime' => $data['completionTime'],
                'outTradeNo' => $data['outTradeNo'],
                'transAmt' => $data['transAmt'],
                'event' => $data['event'],
                'transStatus' => $data['transStatus']
            ], self::getConfig()['key'])) {

            $map['id'] = substr($data['outTradeNo'], 1);
            if ($data['event'] == 'PAYIN') {
                $type = substr($data['outTradeNo'], 0, 1);
                $map['status'] = 0;
//                $map['id'] = 5;
                if ($type == 'R') {//充值
                    $md = AccountRecharge::query()->where($map)->first();
                    if ($md) {
                        $md->trade_no = $data['transNo'];
                        if (WalletService::recharge($md)) return 'ok';
                    }
                } elseif ($type == 'O') {//下单支付
                    $md = MallOrder::query()->where(['id' => $map['id'], 'is_pay' => 0])->first();
                    if ($md) {
                        MallOrder::query()->where(['id' => $map['id'], 'is_pay' => 0])->update(['is_pay' => 1, 'pay_at' => date('Y-m-d H:i:s')]);
                        api_dispatch(new AccountOrderPayEvent($md->user_id, $md->id, get_user_cache('type', $md->user_id)));
                        return 'ok';
                    }
                }
            }
            if ($data['event'] == 'PAYOUT') {
                $map['status'] = 1;
                $md = AccountWithdrawal::query()->where($map)->first();
                $md?->update(['pay_status' => 1]);
                return 'ok';
            }
        }
        return 'fail';
    }

    public static function post($uri, $param)
    {
        $config = self::getConfig();
        $param['mchtId'] = $config['merchant_id'];
        $param['appId'] = $config['appid'];
        $param['countryCode'] = 'BR';
        $param['requestTime'] = date('Y-m-d H:i:s');
        $param['signType'] = 'MD5';
        $param['notifyUrl'] = $config['notifyUrl'];//支付平台后台需配置
        $param['sign'] = self::sign($param, $config['key']);
        $curl = curl_init();
        curl_setopt_array($curl, array(
            CURLOPT_URL => $config['url'] . $uri,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_POST => true,
            CURLOPT_POSTFIELDS => json_encode($param),
            CURLOPT_HTTPHEADER => array('Content-Type: application/json')
        ));
        $response = curl_exec($curl);
        curl_close($curl);
        return json_decode($response, true);
    }

    public static function sign(array $param, string $key): string
    {
        ksort($param);
        $s = urldecode(http_build_query($param)) . $key;
        return strtoupper(md5($s));
    }

    public static function getConfig(bool $refresh = false): array
    {
        if (!self::$config || $refresh) self::$config = array_column(FastappPay::query()->where(['code' => 'sh-pay'])->value('config'), 'text', 'field');
        return self::$config;
    }
}